﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public class PbfBookmark
{
  internal string pbfpath;
  internal List<string> lsVideoPath = new List<string>();
  internal List<ffmepgCmdInfo> timestamps = new List<ffmepgCmdInfo>();
  internal List<(int msec, string bookmark)> book = new List<(int msec, string bookmark)>();
  private static Regex regex = new Regex(@"(?<index>\d)=(?<sec>\d+)\*(?<bookmark>[^\r{nl}*$]+)");

  public PbfBookmark(string pbfpath)
  {
    this.pbfpath = pbfpath;
    ProcessPbfFiles(this.pbfpath);
    GenerateTimestampStrings();
  }

  // 步骤2+3+4：处理所有PBF文件
  private List<(int sec, string bookmark)> ProcessPbfFiles(string filePath)
  {
    book.Clear();
    try
    {
      string content = File.ReadAllText(filePath);
      book.AddRange(ParseBookmarks(content));
    }
    catch (Exception ex)
    {
      //HandleError(filePath, ex);
    }
    return book;
  }

  // 步骤5：生成时间戳字符串
  private List<ffmepgCmdInfo> GenerateTimestampStrings()
  {
    FindVideoFile();
    for (int i = 0; i < book.Count; i += 2)
    {
      if (i + 1 >= book.Count) break;

      var time1 = FormatTime(book[i].msec / 1000);
      var time2 = FormatTime(book[i + 1].msec / 1000);
      string ssto = $"-ss {time1} -to {time2}";

      var sstoname = ssto.Replace("-", "_").Replace(" ", "").Replace(":", "");
      if (lsVideoPath.Count > 0)
      {
        var strFindx = lsVideoPath[0];
        var dir = Path.GetDirectoryName(strFindx);
        var fn = Path.GetFileNameWithoutExtension(strFindx);
        var ext = Path.GetExtension(strFindx);
        var fne = Path.Combine(dir, fn + sstoname + ext);
        var fne2 = Path.Combine($"{fn}{sstoname}{ext}");
        var fnemark = Path.Combine($"{fn}_{book[i].bookmark}{sstoname}{ext}");
        var fneHasmark = !book[i].bookmark.Contains("书签") ? fnemark : fne2;
        var nl = Environment.NewLine;
        var startcmd = "start \"\" ";
        var cmd = $"{nl}{startcmd}ffmpeg - hide_banner {ssto} -i \"{strFindx}\" -c:v copy -n \"{fne}\"";
        string hasmark = $"{startcmd}ffmpeg -hide_banner {ssto} -i \"{Path.GetFileName(strFindx)}\" -c:v copy -n \"{fneHasmark}\"{nl}";
        var cmdHasmark = $"{nl}" +
          $"pushd .{nl}" +
          $"cd /d \"{dir}\"{nl}" +
          hasmark +
          $"popd";
        var cmdRemHasmark = $"rem {nl}" +
          $"rem pushd .{nl}" +
          $"rem cd /d \"{dir}\"{nl}" +
          $"rem {hasmark}" +
          $"rem popd";
        ffmepgCmdInfo info = new ffmepgCmdInfo()
        {
          bookmark2 = $"{book[i].bookmark},{book[i + 1].bookmark}",
          ssto = ssto,
          cmd = cmd,
          dir = dir,
          cmdHasmark = cmdHasmark,
          cmdRemHasmark = cmdRemHasmark,
          nameHasmark = fneHasmark,
        };
        timestamps.Add(info);
      }
    }
    return timestamps;
  }

  // 时间格式化（保持不变）
  static string FormatTime(int totalSeconds)
  {
    int hours = totalSeconds / 3600;
    int minutes = (totalSeconds % 3600) / 60;
    int seconds = totalSeconds % 60;
    return $"{hours:D2}:{minutes:D2}:{seconds:D2}";
  }


  // 步骤3：解析书签数据
  static List<(int sec, string bookmark)> ParseBookmarks(string content)
  {
    var results = new List<(int, string)>();

    foreach (Match match in regex.Matches(content))
    {
      if (int.TryParse(match.Groups["sec"].Value, out int sec))
      {
        results.Add((sec, match.Groups["bookmark"].Value.Trim()));
      }
    }
    return results;
  }

  // 结果输出
  public override string ToString()
  {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.AppendLine($@"    Segments: {timestamps.Count:D2} -> ""{Path.GetFileName(pbfpath)}""");
    for (int i = 0; i < timestamps.Count; i++)
    {
      var dd = timestamps[i];
      stringBuilder.AppendLine($"      {i + 1:D2}: {dd.bookmark2} ({dd.ssto})");
      //stringBuilder.AppendLine($"      {i + 1:D2}: {dd.bookmark2} ({dd.ssto}) {dd.cmd}");
    }
    return stringBuilder.ToString();
  }

  public List<string> FindVideoFile()
  {
    lsVideoPath.Clear();
    try
    {
      if (string.IsNullOrEmpty(pbfpath) || !File.Exists(pbfpath))
        return lsVideoPath;

      string directory = Path.GetDirectoryName(pbfpath);
      string nameWithoutExt = Path.GetFileNameWithoutExtension(pbfpath);

      // 按优先级顺序检查的扩展名列表
      string[] extensions = { ".mov", ".mp4", ".m4a", ".3gp", ".3g2", ".mj2", ".wmv", ".mkv" };

      foreach (string ext in extensions)
      {
        string targetPath = Path.Combine(directory, nameWithoutExt + ext);
        if (File.Exists(targetPath))
        {
          lsVideoPath.Add(targetPath);
        }
      }
    }
    catch
    {
      // 可根据需要添加异常处理
    }
    return lsVideoPath;
  }

}

internal struct ffmepgCmdInfo
{
  public string bookmark2;
  public string ssto;
  public string cmd;
  public string dir;
  public string cmdRemHasmark;
  public string cmdHasmark;
  public string nameHasmark;
}